<html>
   <head>
      <link rel="stylesheet" href="styles.css">
   </head>
   <body>
      Size: <input id="size-input" type="text" value="500000" />
      Times: <input id="times-input" type="text" value="2" />
      <p></p>
      <button id="sort-btn">Sort</button>
      <button id="sort-with-timeout">Sort with timeout</button>
      <button id="sort-with-worker">Sort with Worker</button>
      <hr />
      <h2>Result:</h2>
      <div id="result"></div>
      <div id="loader" class="loader"></div>
      <script src="main.js"></script>
   </body>
</html>
if (typeof (Worker) === "undefined") {
   alert("Ops, your browser doesn't support HTML5 Web Worker! Please choose another modern browser and try again.");
}
/* elements declare */
var sortBtn = document.getElementById('sort-btn');
var sortWithTimeoutBtn = document.getElementById('sort-with-timeout');
var sortWithWorkerBtn = document.getElementById('sort-with-worker');
var sizeInput = document.getElementById('size-input');
var timesInput = document.getElementById('times-input');
var resultDiv = document.getElementById('result');
var loaderDiv = document.getElementById('loader');

/* event binding */
sortBtn.addEventListener('click', sort);
sortWithTimeoutBtn.addEventListener('click', sortWithTimeout);
sortWithWorkerBtn.addEventListener('click', sortWithWorker);

loaderDiv.style.display = 'none';

/* functions */
function ascSort(sourceArr) {
   var ascArr = sourceArr.slice();
   ascArr.sort(function (a, b) {
      return a - b;
   });
}

function finished(start, end) {
   var time = end - start;
   resultDiv.innerText = time + 'ms';
   resultDiv.style.display = 'block';
   loaderDiv.style.display = 'none';
}

function loading() {
   resultDiv.style.display = 'none';
   loaderDiv.style.display = 'block';
}

function genDescArr(n) {
   var result = [];
   while (--n >= 0) {
      result.push(n);
   }
   return result;
}

function sort() {
   var size = parseInt(sizeInput.value);
   var times = parseInt(timesInput.value);
   var descArr = genDescArr(size);
   var start = performance.now();
   loading();
   while (--times >= 0) {
      ascSort(descArr);
   }
   var end = performance.now();
   finished(start, end);
}

function sortWithTimeout() {
   var size = parseInt(sizeInput.value);
   var totalTimes = parseInt(timesInput.value);
   var times = totalTimes;
   var count = 0;
   var descArr = genDescArr(size);
   var start = performance.now();
   loading();
   while (--times >= 0) {
      setTimeout(function () {
         ascSort(descArr);
         if (++count === totalTimes) {
            end = performance.now();
            finished(start, end);
         }
      });
   }
}

function sortWithWorker() {
   var size = parseInt(sizeInput.value);
   var totalTimes = parseInt(timesInput.value);
   var times = totalTimes;
   var count = 0;
   var descArr = genDescArr(size);
   var start = performance.now();
   loading();
   while (--times >= 0) {
      var worker = new Worker('worker.js');
      worker.postMessage(descArr);
      worker.onmessage = function (e) {
         if (++count === totalTimes) {
            end = performance.now();
            finished(start, end);
         }
      }
   }
}
.loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 120px;
  height: 120px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
self.onmessage = function(e) {
   var descArr = e.data;
   var ascArr = ascSort(descArr);
   self.postMessage(ascArr);
}

function ascSort(sourceArr) {
   var ascArr = sourceArr.slice();
   ascArr.sort(function (a, b) {
      return a - b;
   });
   return ascArr;
}